package simplechat;

// This file contains material supporting section 3.7 of the textbook:
// "Object Oriented Software Engineering" and is issued under the open-source
// license found at www.lloseng.com

import java.io.IOException;
import java.util.HashMap;

import ocsf.server.AbstractServer;
import ocsf.server.ConnectionToClient;

/**
 * This class overrides some of the methods in the abstract superclass in order
 * to give more functionality to the server.
 * 
 * @author Dr Timothy C. Lethbridge
 * @author Dr Robert Lagani&egrave;re
 * @author Fran&ccedil;ois B&eacute;langer
 * @author Paul Holden
 * @version July 2000
 */
public class EchoServer extends AbstractServer
{
  // Class variables *************************************************

  /**
   * The default port to listen on.
   */
  final public static int DEFAULT_PORT = 5555;

  // Constructors ****************************************************

  /**
   * Constructs an instance of the echo server.
   * 
   * @param port
   *          The port number to connect on.
   */
  public EchoServer(int port)
  {
    super(port);
  }

  /**
   * Used to store account information.
   */
  private HashMap<String, String> users = new HashMap<>();

  // Instance methods ************************************************

  /**
   * This method handles any messages received from the client.
   * 
   * @param msg
   *          The message received from the client.
   * @param client
   *          The connection from which the message originated.
   */
  public void handleMessageFromClient(Object msg, ConnectionToClient client)
  {
    if (client.getInfo("username") == null)
    {
      String username = (String) msg;
      client.setInfo("username", username);
      try
      {
        if (users.containsKey(username))
        {
          System.out.println("Username recieved: " + username);
          client.sendToClient("Geef uw Password");

        }
        else
        {
          System.out.println("Nieuwe username recieved: " + username);
          client
              .sendToClient("Welkom, nieuwe gebruiker, voer een wachtwoord in");
        }

      }
      catch (IOException e)
      {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
    }
    else if (client.getInfo("loggedin") == null)
    {

      if (users.containsKey(client.getInfo("username")))
      {
        if (users.get((String) client.getInfo("username")).equals((String) msg))
        {
          this.sendToAllClients(client.getInfo("username") + " is ingelogd");
          client.setInfo("loggedin", true);
        }
        else
        {
          try
          {
            client.sendToClient("Het wachtwoord is fout");
          }
          catch (IOException e)
          {
            // TODO Auto-generated catch block
            e.printStackTrace();
          }
        }
      }
      else
      {
        users.put((String) client.getInfo("username"), (String) msg);
        client.setInfo("loggedin", true);
        this.sendToAllClients(client.getInfo("username") + " is ingelogd");
      }

    }
    else
    {

      System.out.println("Message received: " + msg + " from " + client);
      this.sendToAllClients(msg);
    }
  }

  /**
   * This method overrides the one in the superclass. Called when the server
   * starts listening for connections.
   */
  protected void serverStarted()
  {
    System.out.println("Server listening for connections on port " + getPort());
  }

  /**
   * This method overrides the one in the superclass. Called when the server
   * stops listening for connections.
   */
  protected void serverStopped()
  {
    System.out.println("Server has stopped listening for connections.");
  }

  // Class methods ***************************************************

  /**
   * This method is responsible for the creation of the server instance (there
   * is no UI in this phase).
   * 
   * @param args
   *          [0] The port number to listen on. Defaults to 5555 if no argument
   *          is entered.
   */
  public static void main(String[] args)
  {
    int port = 0; // Port to listen on

    try
    {
      port = Integer.parseInt(args[0]); // Get port from command line
    }
    catch (Throwable t)
    {
      port = DEFAULT_PORT; // Set port to 5555
    }

    EchoServer sv = new EchoServer(port);

    try
    {
      sv.listen(); // Start listening for connections
    }
    catch (Exception ex)
    {
      System.out.println("ERROR - Could not listen for clients!");
    }
  }

  /**
   * Hook method called each time a new client connection is accepted. The
   * default implementation does nothing.
   * 
   * @param client
   *          the connection connected to the client.
   */
  protected void clientConnected(ConnectionToClient client)
  {
    System.out.println("A client connected.");
    try
    {
      client.sendToClient("Insert Username");
    }
    catch (IOException e)
    {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }

  /**
   * Hook method called each time this server disconnects a client. The default
   * implementation does nothing. The method may be overridden by subclasses but
   * should remains synchronized.
   * 
   * @param client
   *          the connection with the client.
   */
  synchronized protected void clientDisconnected(ConnectionToClient client)
  {
    System.out.println("A client disconnected.");
  }

  synchronized protected void clientException(ConnectionToClient client,
      Throwable exception)
  {
    try
    {
      client.close();
    }
    catch (IOException ex)
    {
      System.out.println("Error, a client has gone, but dont wanna go");

    }
  }

}
// End of EchoServer class
